/* @internal */
namespace ts.codefix {
    const fixId = "correctQualifiedNameToIndexedAccessType";
    const errorCodes = [Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code];
    registerCodeFix({
        errorCodes,
        getCodeActions(context) {
            const qualifiedName = getQualifiedName(context.sourceFile, context.span.start);
            if (!qualifiedName) return undefined;
            const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, qualifiedName));
            const newText = `${qualifiedName.left.text}["${qualifiedName.right.text}"]`;
            return [createCodeFixAction(fixId, changes, [Diagnostics.Rewrite_as_the_indexed_access_type_0, newText], fixId, Diagnostics.Rewrite_all_as_indexed_access_types)];
        },
        fixIds: [fixId],
        getAllCodeActions: (context) => codeFixAll(context, errorCodes, (changes, diag) => {
            const q = getQualifiedName(diag.file, diag.start);
            if (q) {
                doChange(changes, diag.file, q);
            }
        }),
    });

    function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & { left: Identifier } | undefined {
        const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isQualifiedName)!;
        Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
        return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined;
    }

    function doChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, qualifiedName: QualifiedName): void {
        const rightText = qualifiedName.right.text;
        const replacement = createIndexedAccessTypeNode(
            createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined),
            createLiteralTypeNode(createLiteral(rightText)));
        changeTracker.replaceNode(sourceFile, qualifiedName, replacement);
    }
}
